
<!DOCTYPE html>

<html>
  
<!-- Mirrored from docs.sympy.org/latest/guides/booleans.html by HTTrack Website Copier/3.x [XR&CO'2014], Sat, 15 Jan 2022 03:24:00 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />

    <title>Symbolic and fuzzy booleans &#8212; SymPy 1.9 documentation</title>
    <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="../_static/default.css" />
    <link rel="stylesheet" type="text/css" href="../_static/graphviz.css" />
    <link rel="stylesheet" type="text/css" href="../_static/plot_directive.css" />
    <link rel="stylesheet" type="text/css" href="../../../live.sympy.org/static/live-core.css" />
    <link rel="stylesheet" type="text/css" href="../../../live.sympy.org/static/live-autocomplete.css" />
    <link rel="stylesheet" type="text/css" href="../../../live.sympy.org/static/live-sphinx.css" />
    
    <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
    <script src="../_static/jquery.js"></script>
    <script src="../_static/underscore.js"></script>
    <script src="../_static/doctools.js"></script>
    <script src="../../../live.sympy.org/static/utilities.js"></script>
    <script src="../../../live.sympy.org/static/external/classy.js"></script>
    <script src="../../../live.sympy.org/static/live-core.js"></script>
    <script src="../../../live.sympy.org/static/live-autocomplete.js"></script>
    <script src="../../../live.sympy.org/static/live-sphinx.js"></script>
    
    <link rel="shortcut icon" href="../_static/sympy-notailtext-favicon.ico"/>
    <link href="booleans.html" rel="canonical" />
    
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Gotchas and Pitfalls" href="../gotchas.html" />
    <link rel="prev" title="Assumptions" href="assumptions.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="../gotchas.html" title="Gotchas and Pitfalls"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="assumptions.html" title="Assumptions"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">SymPy 1.9 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">SymPy Guides</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="#">Symbolic and fuzzy booleans</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="symbolic-and-fuzzy-booleans">
<span id="booleans"></span><h1>Symbolic and fuzzy booleans<a class="headerlink" href="#symbolic-and-fuzzy-booleans" title="Permalink to this headline">¶</a></h1>
<p>This page described what a symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> in SymPy is and also
how that relates to three-valued fuzzy-bools that are used in many parts of
SymPy. It also discusses some common problems that arise when writing code
that uses three-valued logic and how to handle them correctly.</p>
<section id="symbolic-boolean-vs-three-valued-bool">
<h2>Symbolic Boolean vs three valued bool<a class="headerlink" href="#symbolic-boolean-vs-three-valued-bool" title="Permalink to this headline">¶</a></h2>
<p>Assumptions queries like <code class="docutils literal notranslate"><span class="pre">x.ispositive</span></code> give fuzzy-bool <code class="docutils literal notranslate"><span class="pre">True</span></code>,
<code class="docutils literal notranslate"><span class="pre">False</span></code> or <code class="docutils literal notranslate"><span class="pre">None</span></code> results <a class="footnote-reference brackets" href="#fuzzy" id="id1">1</a>. These are low-level Python objects
rather than SymPy’s symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> expressions.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">Symbol</span><span class="p">,</span> <span class="n">symbols</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">xpos</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;xpos&#39;</span><span class="p">,</span> <span class="n">positive</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">xneg</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;xneg&#39;</span><span class="p">,</span> <span class="n">negative</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">xpos</span><span class="o">.</span><span class="n">is_positive</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">xneg</span><span class="o">.</span><span class="n">is_positive</span><span class="p">)</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">is_positive</span><span class="p">)</span>
<span class="go">None</span>
</pre></div>
</div>
<p>A <code class="docutils literal notranslate"><span class="pre">None</span></code> result as a fuzzy-bool should be interpreted as meaning “maybe” or
“unknown”.</p>
<p>An example of a symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> class in SymPy can be found when
using inequalities. When an inequality is not known to be true or false a
<a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> can represent indeterminate results symbolically:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">xpos</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">xneg</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="go">x &gt; 0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">&lt;class &#39;sympy.core.relational.StrictGreaterThan&#39;&gt;</span>
</pre></div>
</div>
<p>The last example shows what happens when an inequality is indeterminate: we
get an instance of <a class="reference internal" href="../modules/core.html#sympy.core.relational.StrictGreaterThan" title="sympy.core.relational.StrictGreaterThan"><code class="xref py py-class docutils literal notranslate"><span class="pre">StrictGreaterThan</span></code></a> which represents the
inequality as a symbolic expression. Internally when attempting to evaluate an
inequality like <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">&gt;</span> <span class="pre">b</span></code> SymPy will compute <code class="docutils literal notranslate"><span class="pre">(a</span> <span class="pre">-</span> <span class="pre">b).is_extended_positive</span></code>.
If the result is <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code> then SymPy’s symbolic <code class="docutils literal notranslate"><span class="pre">S.true</span></code> or
<code class="docutils literal notranslate"><span class="pre">S.false</span></code> will be returned. If the result is <code class="docutils literal notranslate"><span class="pre">None</span></code> then an unevaluated
<a class="reference internal" href="../modules/core.html#sympy.core.relational.StrictGreaterThan" title="sympy.core.relational.StrictGreaterThan"><code class="xref py py-class docutils literal notranslate"><span class="pre">StrictGreaterThan</span></code></a> is returned as shown for <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> above.</p>
<p>It is not obvious that queries like <code class="docutils literal notranslate"><span class="pre">xpos</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> return <code class="docutils literal notranslate"><span class="pre">S.true</span></code> rather than
<code class="docutils literal notranslate"><span class="pre">True</span></code> because both objects display in the same way but we can check this
using the Python <code class="docutils literal notranslate"><span class="pre">is</span></code> operator:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">S</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">xpos</span><span class="o">.</span><span class="n">is_positive</span> <span class="ow">is</span> <span class="kc">True</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">xpos</span><span class="o">.</span><span class="n">is_positive</span> <span class="ow">is</span> <span class="n">S</span><span class="o">.</span><span class="n">true</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">(</span><span class="n">xpos</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">True</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">(</span><span class="n">xpos</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">is</span> <span class="n">S</span><span class="o">.</span><span class="n">true</span>
<span class="go">True</span>
</pre></div>
</div>
<p>There is no general symbolic analogue of <code class="docutils literal notranslate"><span class="pre">None</span></code> in SymPy. In the cases where
a low-level assumptions query gives <code class="docutils literal notranslate"><span class="pre">None</span></code> the symbolic query will result in
an unevaluated symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> (e.g, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code>).  We can use a
symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> as part of a symbolic expression such as a
<a class="reference internal" href="../modules/functions/elementary.html#sympy.functions.elementary.piecewise.Piecewise" title="sympy.functions.elementary.piecewise.Piecewise"><code class="xref py py-class docutils literal notranslate"><span class="pre">Piecewise</span></code></a>:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">Piecewise</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span> <span class="o">=</span> <span class="n">Piecewise</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="kc">True</span><span class="p">))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span>
<span class="go">Piecewise((1, x &gt; 0), (2, True))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="go">1</span>
</pre></div>
</div>
<p>Here <code class="docutils literal notranslate"><span class="pre">p</span></code> represents an expression that will be equal to <code class="docutils literal notranslate"><span class="pre">1</span></code> if <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code>
or otherwise it will be equal to <code class="docutils literal notranslate"><span class="pre">2</span></code>. The unevaluated <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> inequality
<code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> represents the condition for deciding the value of the expression
symbolically. When we substitute a value for <code class="docutils literal notranslate"><span class="pre">x</span></code> the inequality will resolve
to <code class="docutils literal notranslate"><span class="pre">S.true</span></code> and then the <a class="reference internal" href="../modules/functions/elementary.html#sympy.functions.elementary.piecewise.Piecewise" title="sympy.functions.elementary.piecewise.Piecewise"><code class="xref py py-class docutils literal notranslate"><span class="pre">Piecewise</span></code></a> can evaluate to <code class="docutils literal notranslate"><span class="pre">1</span></code> or <code class="docutils literal notranslate"><span class="pre">2</span></code>.</p>
<p>The same will not work when using a fuzzy-bool instead of a symbolic
<a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a>:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">p2</span> <span class="o">=</span> <span class="n">Piecewise</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="n">x</span><span class="o">.</span><span class="n">is_positive</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="kc">True</span><span class="p">))</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">Second argument must be a Boolean, not `NoneType`</span>
</pre></div>
</div>
<p>The <a class="reference internal" href="../modules/functions/elementary.html#sympy.functions.elementary.piecewise.Piecewise" title="sympy.functions.elementary.piecewise.Piecewise"><code class="xref py py-class docutils literal notranslate"><span class="pre">Piecewise</span></code></a> can not use <code class="docutils literal notranslate"><span class="pre">None</span></code> as the condition because unlike the
inequality <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> it gives no information. With the inequality it is
possible to decide in future if the condition might <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code>
once a value for <code class="docutils literal notranslate"><span class="pre">x</span></code> is known. A value of <code class="docutils literal notranslate"><span class="pre">None</span></code> can not be used in that
way so it is rejected.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>We can use <code class="docutils literal notranslate"><span class="pre">True</span></code> in the <a class="reference internal" href="../modules/functions/elementary.html#sympy.functions.elementary.piecewise.Piecewise" title="sympy.functions.elementary.piecewise.Piecewise"><code class="xref py py-class docutils literal notranslate"><span class="pre">Piecewise</span></code></a> because <code class="docutils literal notranslate"><span class="pre">True</span></code> sympifies
to <code class="docutils literal notranslate"><span class="pre">S.true</span></code>. Sympifying <code class="docutils literal notranslate"><span class="pre">None</span></code> just gives <code class="docutils literal notranslate"><span class="pre">None</span></code> again which
is not a valid symbolic SymPy object.</p>
</div>
<p>There are many other symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> types in SymPy. The same
considerations about the differences between fuzzy bool and symbolic
<a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> apply to all other SymPy <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> types. To give
a different example there is <a class="reference internal" href="../modules/sets.html#sympy.sets.conditionset.Contains" title="sympy.sets.conditionset.Contains"><code class="xref py py-class docutils literal notranslate"><span class="pre">Contains</span></code></a> which represents the
statement that an object is contained in a set:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">Reals</span><span class="p">,</span> <span class="n">Contains</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">,</span> <span class="n">real</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">y</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;y&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Contains</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">Reals</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Contains</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">Reals</span><span class="p">)</span>
<span class="go">Contains(y, Reals)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Contains</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">Reals</span><span class="p">)</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">True</span>
</pre></div>
</div>
<p>The Python operator corresponding to <a class="reference internal" href="../modules/sets.html#sympy.sets.conditionset.Contains" title="sympy.sets.conditionset.Contains"><code class="xref py py-class docutils literal notranslate"><span class="pre">Contains</span></code></a> is <code class="docutils literal notranslate"><span class="pre">in</span></code>. A quirk of
<code class="docutils literal notranslate"><span class="pre">in</span></code> is that it can only evaluate to a <code class="docutils literal notranslate"><span class="pre">bool</span></code> (<code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code>) so
if the result is indeterminate then an exception will be raised:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">I</span>
<span class="gp">&gt;&gt;&gt; </span><span class="mi">2</span> <span class="ow">in</span> <span class="n">Reals</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">I</span> <span class="ow">in</span> <span class="n">Reals</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="ow">in</span> <span class="n">Reals</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">y</span> <span class="ow">in</span> <span class="n">Reals</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">did not evaluate to a bool: (-oo &lt; y) &amp; (y &lt; oo)</span>
</pre></div>
</div>
<p>The exception can be avoided by using <code class="docutils literal notranslate"><span class="pre">Contains(x,</span> <span class="pre">Reals)</span></code> or
<code class="docutils literal notranslate"><span class="pre">Reals.contains(x)</span></code> rather than <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">Reals</span></code>.</p>
</section>
<section id="three-valued-logic-with-fuzzy-bools">
<h2>Three-valued logic with fuzzy bools<a class="headerlink" href="#three-valued-logic-with-fuzzy-bools" title="Permalink to this headline">¶</a></h2>
<p>Whether we use the fuzzy-bool or symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> we always need to be
aware of the possibility that a query might be indeterminate. How to write
code that handles this is different in the two cases though. We will look at
fuzzy-bools first.</p>
<p>Consider the following function:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">both_positive</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="gp">... </span>    <span class="sd">&quot;&quot;&quot;ask whether a and b are both positive&quot;&quot;&quot;</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">a</span><span class="o">.</span><span class="n">is_positive</span> <span class="ow">and</span> <span class="n">b</span><span class="o">.</span><span class="n">is_positive</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="kc">True</span>
<span class="gp">... </span>    <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="kc">False</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">both_positive</span></code> function is supposed to tell us whether or not <code class="docutils literal notranslate"><span class="pre">a</span></code> and
<code class="docutils literal notranslate"><span class="pre">b</span></code> are both positive. However the <code class="docutils literal notranslate"><span class="pre">both_positive</span></code> function will fail if
either of the <code class="docutils literal notranslate"><span class="pre">is_positive</span></code> queries gives <code class="docutils literal notranslate"><span class="pre">None</span></code>:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">S</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)))</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">),</span> <span class="n">S</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)))</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">)</span> <span class="c1"># may or may not be positive</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">x</span><span class="p">))</span>
<span class="go">False</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>We need to sympify the arguments to this function using <code class="docutils literal notranslate"><span class="pre">S</span></code>
because the assumptions are only defined on SymPy objects and not
regular Python <code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code> objects.</p>
</div>
<p>Here <code class="docutils literal notranslate"><span class="pre">False</span></code> is incorrect because it is <em>possible</em> that <code class="docutils literal notranslate"><span class="pre">x</span></code> is positive in
which case both arguments would be positive. We get <code class="docutils literal notranslate"><span class="pre">False</span></code> here because
<code class="docutils literal notranslate"><span class="pre">x.is_positive</span></code> gives <code class="docutils literal notranslate"><span class="pre">None</span></code> and Python will treat <code class="docutils literal notranslate"><span class="pre">None</span></code> as “falsey”.</p>
<p>In order to handle all possible cases correctly we need to separate the logic
for identifying the <code class="docutils literal notranslate"><span class="pre">True</span></code> and <code class="docutils literal notranslate"><span class="pre">False</span></code> cases. An improved function might
be:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">both_positive_better</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="gp">... </span>    <span class="sd">&quot;&quot;&quot;ask whether a and b are both positive&quot;&quot;&quot;</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">a</span><span class="o">.</span><span class="n">is_positive</span> <span class="ow">is</span> <span class="kc">False</span> <span class="ow">or</span> <span class="n">b</span><span class="o">.</span><span class="n">is_positive</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="kc">False</span>
<span class="gp">... </span>    <span class="k">elif</span> <span class="n">a</span><span class="o">.</span><span class="n">is_positive</span> <span class="ow">is</span> <span class="kc">True</span> <span class="ow">and</span> <span class="n">b</span><span class="o">.</span><span class="n">is_positive</span> <span class="ow">is</span> <span class="kc">True</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="kc">True</span>
<span class="gp">... </span>    <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="kc">None</span>
</pre></div>
</div>
<p>This function now can handle all cases of <code class="docutils literal notranslate"><span class="pre">True</span></code>, <code class="docutils literal notranslate"><span class="pre">False</span></code> or <code class="docutils literal notranslate"><span class="pre">None</span></code> for
both <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> and will always return a fuzzy bool representing whether
the statement “<code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> are both positive” is true, false or unknown:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">)))</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">S</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)))</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">y</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;y&#39;</span><span class="p">,</span> <span class="n">positive</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">x</span><span class="p">))</span>
<span class="go">None</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">),</span> <span class="n">x</span><span class="p">))</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">y</span><span class="p">))</span>
<span class="go">True</span>
</pre></div>
</div>
<p>Another case that we need to careful of when using fuzzy-bools is negation
with Python’s <code class="docutils literal notranslate"><span class="pre">not</span></code> operator e.g.:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">is_positive</span><span class="p">)</span>
<span class="go">None</span>
<span class="gp">&gt;&gt;&gt; </span><span class="ow">not</span> <span class="n">x</span><span class="o">.</span><span class="n">is_positive</span>
<span class="go">True</span>
</pre></div>
</div>
<p>The correct negation of a fuzzy bool <code class="docutils literal notranslate"><span class="pre">None</span></code> is <code class="docutils literal notranslate"><span class="pre">None</span></code> again. If we do not
know whether the statement “<code class="docutils literal notranslate"><span class="pre">x</span></code> is positive” is <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code> then
we also do not know whether its negation “<code class="docutils literal notranslate"><span class="pre">x</span></code> is not positive” is <code class="docutils literal notranslate"><span class="pre">True</span></code>
or <code class="docutils literal notranslate"><span class="pre">False</span></code>. The reason we get <code class="docutils literal notranslate"><span class="pre">True</span></code> instead is again because <code class="docutils literal notranslate"><span class="pre">None</span></code> is
considered “falsey”. When <code class="docutils literal notranslate"><span class="pre">None</span></code> is used with a logical operator such as
<code class="docutils literal notranslate"><span class="pre">not</span></code> it will first be converted to a <code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code> and then negated:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="nb">bool</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="ow">not</span> <span class="nb">bool</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="ow">not</span> <span class="kc">None</span>
<span class="go">True</span>
</pre></div>
</div>
<p>The fact that <code class="docutils literal notranslate"><span class="pre">None</span></code> is treated as falsey can be useful if used correctly.
For example we may want to do something only if <code class="docutils literal notranslate"><span class="pre">x</span></code> is known to positive in
which case we can do</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">,</span> <span class="n">positive</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">is_positive</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;x is definitely positive&quot;</span><span class="p">)</span>
<span class="gp">... </span><span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;x may or may not be positive&quot;</span><span class="p">)</span>
<span class="go">x is definitely positive</span>
</pre></div>
</div>
<p>Provided we understand that an alternate condition branch refers to two cases
(<code class="docutils literal notranslate"><span class="pre">False</span></code> and <code class="docutils literal notranslate"><span class="pre">None</span></code>) then this can be a useful way of writing
conditionals.  When we really do need to distinguish all cases then we need to
use things like <code class="docutils literal notranslate"><span class="pre">x.is_positive</span> <span class="pre">is</span> <span class="pre">False</span></code>.  What we need to be careful of
though is using Python’s binary logic operators like <code class="docutils literal notranslate"><span class="pre">not</span></code> or <code class="docutils literal notranslate"><span class="pre">and</span></code> with
fuzzy bools as they will not handle the indeterminate case correctly.</p>
<p>In fact SymPy has internal functions that are designed to handle fuzzy-bools
correctly:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy.core.logic</span> <span class="kn">import</span> <span class="n">fuzzy_not</span><span class="p">,</span> <span class="n">fuzzy_and</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">fuzzy_not</span><span class="p">(</span><span class="kc">True</span><span class="p">))</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">fuzzy_not</span><span class="p">(</span><span class="kc">False</span><span class="p">))</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">fuzzy_not</span><span class="p">(</span><span class="kc">None</span><span class="p">))</span>
<span class="go">None</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">fuzzy_and</span><span class="p">([</span><span class="kc">True</span><span class="p">,</span> <span class="kc">True</span><span class="p">]))</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">fuzzy_and</span><span class="p">([</span><span class="kc">True</span><span class="p">,</span> <span class="kc">None</span><span class="p">]))</span>
<span class="go">None</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">fuzzy_and</span><span class="p">([</span><span class="kc">False</span><span class="p">,</span> <span class="kc">None</span><span class="p">]))</span>
<span class="go">False</span>
</pre></div>
</div>
<p>Using the <code class="docutils literal notranslate"><span class="pre">fuzzy_and</span></code> function we can write the <code class="docutils literal notranslate"><span class="pre">both_positive</span></code> function
more simply:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">both_positive_best</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="gp">... </span>    <span class="sd">&quot;&quot;&quot;ask whether a and b are both positive&quot;&quot;&quot;</span>
<span class="gp">... </span>    <span class="k">return</span> <span class="n">fuzzy_and</span><span class="p">([</span><span class="n">a</span><span class="o">.</span><span class="n">is_positive</span><span class="p">,</span> <span class="n">b</span><span class="o">.</span><span class="n">is_positive</span><span class="p">])</span>
</pre></div>
</div>
<p>Making use of <code class="docutils literal notranslate"><span class="pre">fuzzy_and</span></code>, <code class="docutils literal notranslate"><span class="pre">fuzzy_or</span></code> and <code class="docutils literal notranslate"><span class="pre">fuzzy_not</span></code> leads to simpler
code and can also reduce the chance of introducing a logic error because the
code can look more like it would in the case of ordinary binary logic.</p>
</section>
<section id="three-valued-logic-with-symbolic-booleans">
<h2>Three-valued logic with symbolic Booleans<a class="headerlink" href="#three-valued-logic-with-symbolic-booleans" title="Permalink to this headline">¶</a></h2>
<p>When working with symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> rather than fuzzy-bool the issue of
<code class="docutils literal notranslate"><span class="pre">None</span></code> silently being treated as falsey does not arise so it is easier not
to end up with a logic error. However instead the indeterminate case will
often lead to an exception being raised if not handled carefully.</p>
<p>We will try to implement the <code class="docutils literal notranslate"><span class="pre">both_positive</span></code> function this time using
symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a>:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">both_positive</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="gp">... </span>    <span class="sd">&quot;&quot;&quot;ask whether a and b are both positive&quot;&quot;&quot;</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">b</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="n">S</span><span class="o">.</span><span class="n">true</span>
<span class="gp">... </span>    <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="n">S</span><span class="o">.</span><span class="n">false</span>
</pre></div>
</div>
<p>The first difference is that we return the symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> objects
<code class="docutils literal notranslate"><span class="pre">S.true</span></code> and <code class="docutils literal notranslate"><span class="pre">S.false</span></code> rather than <code class="docutils literal notranslate"><span class="pre">True</span></code> and <code class="docutils literal notranslate"><span class="pre">False</span></code>. The second
difference is that we test e.g. <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> rather than <code class="docutils literal notranslate"><span class="pre">a.is_positive</span></code>.
Trying this out we get</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">)</span>  <span class="c1"># may or may not be positive</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">cannot determine truth value of Relational</span>
</pre></div>
</div>
<p>What happens now is that testing <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> gives an exception when <code class="docutils literal notranslate"><span class="pre">x</span></code> is
not known to be positive or not positive. More precisely <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> does not
give an exception but <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> does and that is because the <code class="docutils literal notranslate"><span class="pre">if</span></code>
statement implicitly calls <code class="docutils literal notranslate"><span class="pre">bool(x</span> <span class="pre">&gt;</span> <span class="pre">0)</span></code> which raises.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="go">x &gt; 0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">bool</span><span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">cannot determine truth value of Relational</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">if</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;x is positive&quot;</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">cannot determine truth value of Relational</span>
</pre></div>
</div>
<p>The Python expression <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">0</span></code> creates a SymPy <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a>. Since in this
case the <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> can not evaluate to <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code> we get an
unevaluated <a class="reference internal" href="../modules/core.html#sympy.core.relational.StrictGreaterThan" title="sympy.core.relational.StrictGreaterThan"><code class="xref py py-class docutils literal notranslate"><span class="pre">StrictGreaterThan</span></code></a>. Attempting to force that into a
<code class="docutils literal notranslate"><span class="pre">bool</span></code> with <code class="docutils literal notranslate"><span class="pre">bool(x</span> <span class="pre">&gt;</span> <span class="pre">0)</span></code> raises an exception. That is because a regular
Python <code class="docutils literal notranslate"><span class="pre">bool</span></code> must be either <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code> and neither of those
are known to be correct in this case.</p>
<p>The same kind of issue arises when using <code class="docutils literal notranslate"><span class="pre">and</span></code>, <code class="docutils literal notranslate"><span class="pre">or</span></code> or <code class="docutils literal notranslate"><span class="pre">not</span></code> with
symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a>. The solution is to use SymPy’s symbolic
<a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.And" title="sympy.logic.boolalg.And"><code class="xref py py-class docutils literal notranslate"><span class="pre">And</span></code></a>, <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Or" title="sympy.logic.boolalg.Or"><code class="xref py py-class docutils literal notranslate"><span class="pre">Or</span></code></a> and <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Not" title="sympy.logic.boolalg.Not"><code class="xref py py-class docutils literal notranslate"><span class="pre">Not</span></code></a> or equivalently Python’s
bitwise logical operators <code class="docutils literal notranslate"><span class="pre">&amp;</span></code>, <code class="docutils literal notranslate"><span class="pre">|</span></code> and <code class="docutils literal notranslate"><span class="pre">~</span></code>:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">And</span><span class="p">,</span> <span class="n">Or</span><span class="p">,</span> <span class="n">Not</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="go">x &gt; 0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">1</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">cannot determine truth value of Relational</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">And</span><span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">(x &gt; 0) &amp; (x &lt; 1)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">(x &gt; 0) &amp; (x &lt; 1)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Or</span><span class="p">(</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">,</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">(x &gt; 1) | (x &lt; 0)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Not</span><span class="p">(</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">x &gt;= 0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="o">~</span><span class="p">(</span><span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">x &gt;= 0</span>
</pre></div>
</div>
<p>As before we can make a better version of <code class="docutils literal notranslate"><span class="pre">both_positive</span></code> if we avoid
directly using a SymPy <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> in an <code class="docutils literal notranslate"><span class="pre">if</span></code>, <code class="docutils literal notranslate"><span class="pre">and</span></code>, <code class="docutils literal notranslate"><span class="pre">or</span></code>, or <code class="docutils literal notranslate"><span class="pre">not</span></code>.
Instead we can test whether or not the <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> has evaluated to <code class="docutils literal notranslate"><span class="pre">S.true</span></code>
or <code class="docutils literal notranslate"><span class="pre">S.false</span></code>:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">both_positive_better</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="gp">... </span>    <span class="sd">&quot;&quot;&quot;ask whether a and b are both positive&quot;&quot;&quot;</span>
<span class="gp">... </span>    <span class="k">if</span> <span class="p">(</span><span class="n">a</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">is</span> <span class="n">S</span><span class="o">.</span><span class="n">false</span> <span class="ow">or</span> <span class="p">(</span><span class="n">b</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">is</span> <span class="n">S</span><span class="o">.</span><span class="n">false</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="n">S</span><span class="o">.</span><span class="n">false</span>
<span class="gp">... </span>    <span class="k">elif</span> <span class="p">(</span><span class="n">a</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">is</span> <span class="n">S</span><span class="o">.</span><span class="n">true</span> <span class="ow">and</span> <span class="p">(</span><span class="n">b</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">is</span> <span class="n">S</span><span class="o">.</span><span class="n">true</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="n">S</span><span class="o">.</span><span class="n">true</span>
<span class="gp">... </span>    <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="n">And</span><span class="p">(</span><span class="n">a</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="n">b</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
<p>Now with this version we don’t get any exceptions and if the result is
indeterminate we will get a symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> representing the conditions
under which the statement “<code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> are both positive” would be true:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">S</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">S</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">S</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="s2">&quot;x, y&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">(x &gt; 0) &amp; (y + 1 &gt; 0)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive_better</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">S</span><span class="p">(</span><span class="mi">3</span><span class="p">))</span>
<span class="go">x &gt; 0</span>
</pre></div>
</div>
<p>The last case shows that actually using the <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.And" title="sympy.logic.boolalg.And"><code class="xref py py-class docutils literal notranslate"><span class="pre">And</span></code></a> with a condition that is
known to be true simplifies the <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.And" title="sympy.logic.boolalg.And"><code class="xref py py-class docutils literal notranslate"><span class="pre">And</span></code></a>. In fact we have</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">And</span><span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">x &gt; 0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">And</span><span class="p">(</span><span class="mi">4</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">And</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">False</span>
</pre></div>
</div>
<p>What this means is that we can improve <code class="docutils literal notranslate"><span class="pre">both_positive_better</span></code>. The
different cases are not needed at all. Instead we can simply return the
<a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.And" title="sympy.logic.boolalg.And"><code class="xref py py-class docutils literal notranslate"><span class="pre">And</span></code></a> and let it simplify if possible:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">both_positive_best</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="gp">... </span>    <span class="sd">&quot;&quot;&quot;ask whether a and b are both positive&quot;&quot;&quot;</span>
<span class="gp">... </span>    <span class="k">return</span> <span class="n">And</span><span class="p">(</span><span class="n">a</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="n">b</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
<p>Now this will work with any symbolic real objects and produce a symbolic
result. We can also substitute into the result to see how it would work for
particular values:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive_best</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive_best</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">both_positive_best</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="go">x &gt; 0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">condition</span> <span class="o">=</span> <span class="n">both_positive_best</span><span class="p">(</span><span class="n">x</span><span class="o">/</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">condition</span>
<span class="go">(x + y &gt; 0) &amp; (x/y &gt; 0)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">condition</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">(1/y &gt; 0) &amp; (y + 1 &gt; 0)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">condition</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">subs</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="go">True</span>
</pre></div>
</div>
<p>The idea when working with symbolic <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Boolean" title="sympy.logic.boolalg.Boolean"><code class="xref py py-class docutils literal notranslate"><span class="pre">Boolean</span></code></a> objects is as much as possible
to avoid trying to branch on them with <code class="docutils literal notranslate"><span class="pre">if/else</span></code> and other logical operators
like <code class="docutils literal notranslate"><span class="pre">and</span></code> etc. Instead think of computing a condition and passing it around
as a variable. The elementary symbolic operations like <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.And" title="sympy.logic.boolalg.And"><code class="xref py py-class docutils literal notranslate"><span class="pre">And</span></code></a>,
<a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Or" title="sympy.logic.boolalg.Or"><code class="xref py py-class docutils literal notranslate"><span class="pre">Or</span></code></a> and <a class="reference internal" href="../modules/logic.html#sympy.logic.boolalg.Not" title="sympy.logic.boolalg.Not"><code class="xref py py-class docutils literal notranslate"><span class="pre">Not</span></code></a> can then take care of the logic for you.</p>
<p class="rubric">Footnotes</p>
<dl class="footnote brackets">
<dt class="label" id="fuzzy"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p>Note that what is referred to in SymPy as a “fuzzy bool” is really
about using three-valued logic. In normal usage “fuzzy logic” refers to a
system where logical values are continuous in between zero and one which is
something different from three-valued logic.</p>
</dd>
</dl>
</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../index.html">
              <img class="logo" src="../_static/sympylogo.png" alt="Logo"/>
            </a></p>
  <h3><a href="../index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Symbolic and fuzzy booleans</a><ul>
<li><a class="reference internal" href="#symbolic-boolean-vs-three-valued-bool">Symbolic Boolean vs three valued bool</a></li>
<li><a class="reference internal" href="#three-valued-logic-with-fuzzy-bools">Three-valued logic with fuzzy bools</a></li>
<li><a class="reference internal" href="#three-valued-logic-with-symbolic-booleans">Three-valued logic with symbolic Booleans</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="assumptions.html"
                        title="previous chapter">Assumptions</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="../gotchas.html"
                        title="next chapter">Gotchas and Pitfalls</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../_sources/guides/booleans.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="https://docs.sympy.org/latest/search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="../gotchas.html" title="Gotchas and Pitfalls"
             >next</a> |</li>
        <li class="right" >
          <a href="assumptions.html" title="Assumptions"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">SymPy 1.9 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="index.html" >SymPy Guides</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="#">Symbolic and fuzzy booleans</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2021 SymPy Development Team.
      Last updated on Sep 30, 2021.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.1.2.
    </div>
  </body>

<!-- Mirrored from docs.sympy.org/latest/guides/booleans.html by HTTrack Website Copier/3.x [XR&CO'2014], Sat, 15 Jan 2022 03:24:01 GMT -->
</html>